package dev.marsh.sniper;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;

import cn.bingoogolapple.photopicker.activity.BGAPhotoPickerActivity;
import dev.marsh.sniper.ar.tracker.JavaDetectionTracker;
import dev.marsh.sniper.core.BuildConfig;
import dev.marsh.sniper.core.R;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

/**
 * 从相册识别图片
 */
public abstract class PickActivity extends AppCompatActivity {
    {
        try {
            System.loadLibrary("opencv_java3");
        } catch (Exception e) {
            if (BuildConfig.DEBUG) {
                e.printStackTrace();
            }
        }
    }

    private static final int REQUEST_CODE_CHOOSE_PIC_FROM_GALLERY = 666;
    private JavaDetectionTracker mTracker;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mTracker = new JavaDetectionTracker(getApplicationContext());
    }

    public void pick() {
        startActivityForResult(BGAPhotoPickerActivity.newIntent(this, null, 1, null, false), REQUEST_CODE_CHOOSE_PIC_FROM_GALLERY);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_CHOOSE_PIC_FROM_GALLERY) {
            final String picturePath = BGAPhotoPickerActivity.getSelectedImages(data).get(0);

            Observable.just(0)
                    .map(integer -> {
                        Bitmap bitmap = getDecodeAbleBitmap(picturePath);
                        if (bitmap == null) {
                            return false;
                        }

                        Mat mat = new Mat(bitmap.getHeight(), bitmap.getWidth(), CvType.CV_8UC4);
                        Utils.bitmapToMat(bitmap, mat);
                        Mat gray = new Mat();
                        Imgproc.cvtColor(mat, gray, Imgproc.COLOR_BGR2GRAY, 1);
                        Imgproc.equalizeHist(gray, gray);

                        if (mTracker != null) {
                            return mTracker.track(gray);
                        }
                        return false;
                    })
                    .subscribeOn(Schedulers.newThread())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(this::showToast,
                            error -> {
                                if (BuildConfig.DEBUG) {
                                    error.printStackTrace();
                                }
                            });
        }
    }

    /**
     * 将本地图片文件转换成可解码的Bitmap
     */
    private static Bitmap getDecodeAbleBitmap(String picturePath) {
        try {
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(picturePath, options);
            int sampleSize = options.outHeight / 400;
            if (sampleSize <= 0) {
                sampleSize = 1;
            }
            options.inSampleSize = sampleSize;
            options.inJustDecodeBounds = false;

            return BitmapFactory.decodeFile(picturePath, options);
        } catch (Exception e) {
            return null;
        }
    }

    private void showToast(boolean success) {
        Toast.makeText(getApplicationContext(), success ? R.string.sniper_success : R.string.sniper_failure, Toast.LENGTH_SHORT).show();
        if (success) {
            vibrate();
        }
        result(success);
    }

    private void vibrate() {
        Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
        vibrator.vibrate(200);
    }

    protected abstract void result(boolean success);
}
